package io.chenglicun.modules.clc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.chenglicun.common.page.PageData;
import io.chenglicun.common.service.impl.CrudServiceImpl;
import io.chenglicun.modules.clc.dao.ClcVoteDao;
import io.chenglicun.modules.clc.dto.ClcVoteDTO;
import io.chenglicun.modules.clc.dto.ClcVoteOptionDTO;
import io.chenglicun.modules.clc.entity.ClcVoteEntity;
import io.chenglicun.modules.clc.service.ClcVoteOptionService;
import io.chenglicun.modules.clc.service.ClcVoteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 投票
 *
 * @author HB 137664951@qq.com
 * @since 1.0 2023-11-24
 */
@Service
public class ClcVoteServiceImpl extends CrudServiceImpl<ClcVoteDao, ClcVoteEntity, ClcVoteDTO> implements ClcVoteService {

    @Autowired
    private ClcVoteOptionService voteOptionService;


    @Override
    public QueryWrapper<ClcVoteEntity> getWrapper(Map<String, Object> params){
        QueryWrapper<ClcVoteEntity> wrapper = new QueryWrapper<>();


        return wrapper;
    }

    @Override
    public PageData<ClcVoteDTO> page(Map<String, Object> params) {
        PageData<ClcVoteDTO> page = super.page(params);
        List<ClcVoteDTO> list = page.getList();

        setData(list.toArray(new ClcVoteDTO[0]));

        return page;
    }

    @Override
    public ClcVoteDTO get(Long id) {
        ClcVoteDTO dto = super.get(id);

        setData(dto);

        return dto;
    }

    @Override
    public List<ClcVoteDTO> list(Map<String, Object> params) {
        List<ClcVoteDTO> list = super.list(params);

        setData(list.toArray(new ClcVoteDTO[0]));

        return list;
    }

    private void setData(ClcVoteDTO... dtos) {
        if (dtos == null || dtos.length == 0) return;
        List<Long> ids = Arrays.stream(dtos).map(ClcVoteDTO::getId).collect(Collectors.toList());

        List<ClcVoteOptionDTO> list = voteOptionService.getListByVoteIds(ids);

        for (ClcVoteDTO dto : dtos) {
            List<ClcVoteOptionDTO> collect = list.stream().filter(t -> t.getVoteId().equals(dto.getId())).collect(Collectors.toList());
            int sum = collect.stream().mapToInt(ClcVoteOptionDTO::getPoll).sum();
            for (ClcVoteOptionDTO optionDTO : collect) {
                BigDecimal decimal = new BigDecimal(optionDTO.getPoll() * 100);
                optionDTO.setPercentage(optionDTO.getPoll() == 0 || sum == 0 ? "0%" : decimal.divide(new BigDecimal(sum)).setScale(2, RoundingMode.HALF_UP) + "%");
            }
            dto.setVoteOptionList(collect);
        }
    }

    @Override
    @Transactional
    public void save(ClcVoteDTO dto) {
        super.save(dto);

        List<ClcVoteOptionDTO> voteOptionList = dto.getVoteOptionList();
        voteOptionList.forEach(t -> t.setVoteId(dto.getId()));

        voteOptionService.saveBatch(voteOptionList);
    }

    @Override
    @Transactional
    public void update(ClcVoteDTO dto) {
        super.update(dto);

        voteOptionService.deleteByVoteIds(dto.getId());

        List<ClcVoteOptionDTO> voteOptionList = dto.getVoteOptionList();
        voteOptionList.forEach(t -> t.setVoteId(dto.getId()));

        voteOptionService.saveBatch(voteOptionList);
    }

    @Override
    @Transactional
    public void delete(Long[] ids) {
        super.delete(ids);

        voteOptionService.deleteByVoteIds(ids);
    }
}